/*
Copyright (C) 2021-2025 Casa Xu (also Zhiyan Xu) from HIT

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/*
 * LOS_SATA.c
 *
 *  Created on: 2022年11月1日
 *      Author: 64435
 */


#include "LOS_SATA.h"

LOS_SATA_t STA_SATA;

uint8_t TMPACK_SATA[16];

void LOS_SATA_GetState()
{
    LOS_SNP_t SNP_CMD;                  //首部配置结构体
    uint8_t FP_CMD[8];                  //首部内容
    SNP_CMD.SNP_dest = nID_Storage;     //存储板
    SNP_CMD.SNP_source = 0xF0;          //OBC发送
    SNP_CMD.SNP_rec = 0x00;             //内容识别码：存储板遥测请求
    SNP_CMD.SNP_len = 8+8;              //长度（包含首部）
    SNP_CMD.SNP_tran = 0x01;            //0001B,信息传递服务
    LOS_CAN_FirstPart(&SNP_CMD,FP_CMD);
    LOS_CAN_Transmit(LOS_CAN_NUM1, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0X00), FP_CMD, 8);
    LOS_CAN_Transmit(LOS_CAN_NUM2, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0X00), FP_CMD, 8);
    FP_CMD[0]=0X00;
    FP_CMD[1]=0X53;
    FP_CMD[2]=0X51;
    FP_CMD[3]=0X00;
    FP_CMD[4]=0X00;
    FP_CMD[5]=0X0C;
    FP_CMD[6]=0X00;
    FP_CMD[7]=0X00;
    LOS_CAN_Transmit(LOS_CAN_NUM1, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0XFF), FP_CMD, 8);
    LOS_CAN_Transmit(LOS_CAN_NUM2, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0XFF), FP_CMD, 8);
}

/** @fn void LOS_SATA_Control(uint32_t wp, uint32_t rp, uint8_t op1, uint8_t op2, uint8_t op3, uint8_t op4, uint8_t op5)
*   @brief 存储板控制指令
*   @param[in] wp   写指针
*   @param[in] rp   读指针
*   @param[in] op1  数据收发控制 0x00为不操作
*   @param[in] op2  清硬盘数据 0x55为清零  0x00为不操作
*   @param[in] op3  存储板复位 0x55为复位  0x00为不操作
*   @param[in] op4  硬盘上下电 0x55为上电 0xAA为下电 0x00为不操作
*   @param[in] op5  波特率选择 0x00为不操作
*   @note 对存储板进行各种参数配置
*/
void LOS_SATA_Control(uint32_t wp, uint32_t rp, uint8_t op1, uint8_t op2, uint8_t op3, uint8_t op4, uint8_t op5)
{
    LOS_SNP_t SNP_CMD;                  //首部配置结构体
    uint8_t FP_CMD[8];                  //首部内容
    uint32_t wpadd = wp;
    uint32_t rpadd = rp;
    SNP_CMD.SNP_dest = nID_Storage;     //存储板
    SNP_CMD.SNP_source = 0xF0;          //OBC发送
    SNP_CMD.SNP_rec = 0x02;             //内容识别码：存储板控制
    SNP_CMD.SNP_len = 8+8+8;            //长度（包含首部）
    SNP_CMD.SNP_tran = 0x01;            //0001B,信息传递服务
    
    LOS_CAN_FirstPart(&SNP_CMD,FP_CMD);
    LOS_CAN_Transmit(LOS_CAN_NUM1, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0X00), FP_CMD, 8);
    LOS_CAN_Transmit(LOS_CAN_NUM2, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0X00), FP_CMD, 8);
    memcpy(FP_CMD,&wpadd,4);
    memcpy(&FP_CMD[4],&rpadd,4);
    LOS_CAN_Transmit(LOS_CAN_NUM1, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0X01), FP_CMD, 8);
    LOS_CAN_Transmit(LOS_CAN_NUM2, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0X01), FP_CMD, 8);
    FP_CMD[0]=op1;
    FP_CMD[1]=op2;
    FP_CMD[2]=op3;
    FP_CMD[3]=op4;
    FP_CMD[4]=op5;
    FP_CMD[5]=0XFF;
    FP_CMD[6]=0XFF;
    FP_CMD[7]=0XFF;
    LOS_CAN_Transmit(LOS_CAN_NUM1, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0XFF), FP_CMD, 8);
    LOS_CAN_Transmit(LOS_CAN_NUM2, LOS_CAN_IDGen(ACK_NoNeed, 0XF0, nID_Storage, 0XFF), FP_CMD, 8);
}


void LOS_CAN_SATACallBack(LOS_CANMSG_t* can_re)
{
    /* 首部校验用法：首部校验通过/未通过会改变canerrflag的值，所有消息会被先存在缓冲区，canerrflag有效时才会转存，无效时舍弃 */
    uint8_t id_filter[4];
    uint8_t sum = 0;
    uint8_t sum_check = 0;
    static uint8_t canerrflag = 0;     //表示首部校验是否通过，未通过：1，通过：0
    static uint8_t canmsgrec = 0xFF;   //消息类型（对应首部的rec）
    float ang_buf = 0;                 //角度缓冲区
    uint8_t sta_buf;                   //状态缓冲区

    memcpy(id_filter, &(can_re->ID), 4);   //将帧ID分为4个字节存储，便于处理
    if (id_filter[3] == 0x00)        //若为首帧
    {
        sum = can_re->msg[0] + can_re->msg[1] + can_re->msg[2] + can_re->msg[3] + can_re->msg[4] + can_re->msg[5] + can_re->msg[6];
        sum_check = 0x100 - sum;
        if (sum_check == can_re->msg[7])   //校验和检查，消息有效性判断
        {
            canerrflag = 0;
            canmsgrec = can_re->msg[6];  
        }
        else 
        {
           canerrflag = 1; 
        }
    }
    else if (id_filter[3] == 0xFF)   //若为尾帧
    {
        if (canerrflag == 0)
        {
            memcpy(&STA_SATA.wpadd, &(can_re->msg[0]), 4);
            memcpy(&STA_SATA.rpadd, &(can_re->msg[4]), 4);
            memcpy(&TMPACK_SATA[8], &(can_re->msg[0]), 8);
            STA_SATA.tmcnt++;
        }
    }
    else                          //若为中间帧
    {
        if (canerrflag == 0)
        {
            STA_SATA.cameralink_sta = can_re->msg[0];
            STA_SATA.dtspi_sta = can_re->msg[1];
            STA_SATA.cam_sta = can_re->msg[2];
            STA_SATA.sata_sw = can_re->msg[3];
            STA_SATA.baudrate = can_re->msg[4];
            STA_SATA.sata_sta = can_re->msg[5];
            memcpy(&TMPACK_SATA[0], &(can_re->msg[0]), 8);
        }
        canerrflag = 0;
    }
}

void LOS_SATA_PWROn()
{
    LOS_EPS_Switch(1,SWITCH_ON);
    STA_SATA.CMD = 1;
}

void LOS_SATA_PWROff()
{
    LOS_EPS_Switch(1,SWITCH_OFF);
    STA_SATA.CMD = 0;
    STA_SATA.REC = 0;
}